#!/usr/bin/python
# encoding:utf-8
import os
import sys
import re
import platform
import time


class Mfile(object):
    
    def __init__(self, pfile, mode):
        
        self.file_dir = os.path.dirname(pfile)
        self.file_name = os.path.basename(pfile)
        self.file_path = os.path.abspath(pfile)
        self.file_mode = mode
        self.file_md5 = 'md5'
        self.file_uptime = 0
        self.file_uptime_size = 0

        if os.path.isfile(pfile):
            self.file_size = os.path.getsize(pfile)
        else:
            self.file_size = 0
            
        if self.file_size > 2000:
            self.file_get_size = self.file_size - 1000
            self.file_buffer_size = 1000
        else:
            self.file_get_size = self.file_size
            self.file_buffer_size = self.file_size

        try:
            self.file_open = open(self.file_path, self.file_mode)
        except Exception, e:
            open_status = 1
            print e
            sys.exit()

    def move_tell(self, number):
        pass

    def __del__(self):
        pass


def fcp(s , d , show_size_on=0):

    c = 10485760
    sfile = Mfile(s, 'rb')
    dfile = Mfile(d, 'ab+')

    # 修正指针偏移
    if sfile.file_size != 0:
        if (sfile.file_size != dfile.file_size) and (dfile.file_size != 0):

            dfile.file_open.seek(dfile.file_get_size, 0)
            sfile.file_open.seek(dfile.file_get_size, 0)

            if dfile.file_open.read(dfile.file_buffer_size) == sfile.file_open.read(dfile.file_buffer_size):
                sfile.file_open.seek(dfile.file_size, 0)
                dfile.file_open.seek(0, 2)

            elif('yes' == raw_input('overwrite ' + dfile.file_name + ' [yes/no]:')):
                dfile.file_open.close()
                dfile = Mfile(d, 'wb+')
                sfile.file_open.seek(0, 0)
            else:
                sfile.file_open.seek(0, 2)
                dfile.file_open.seek(0, 2)

        elif sfile.file_size == dfile.file_size :
            print 'File exists:', dfile.file_path,
            sfile.file_open.seek(0, 2)

    # 开始复制
    dfile.file_uptime = time.time()
    dfile_tell = sfile.file_open.tell()
    if (sfile.file_size == 0):
        print (sfile.file_name) + ' ' * (50 - len(sfile.file_name)), '100% [' + ('*' * 50) + '] 0.0MB/s   | 0.0KB'
    else:
        while(sfile.file_open.tell() != sfile.file_size):
            buffer = sfile.file_open.read(c)
            dfile.file_open.write(buffer)
            
            if (show_size_on == 1):
                dfile.file_uptime_size = (sfile.file_open.tell() - dfile_tell) / (time.time() - dfile.file_uptime)
                show_size(sfile.file_size , sfile.file_open.tell() , dfile.file_name , dfile.file_uptime_size)
                # time.sleep(0.2)
        else:
            print ''

    del sfile
    del dfile



def dcp(s, d, jc=0, mshow=0):
    s = os.path.abspath(s)
    d = os.path.abspath(d)

    if (s == d) or (s == d + '/' + os.path.basename(s)):
        print 'cp :', '\'' + s + '\'', 'and', '\'' + d + '\'', ': are the same file'
        sys.exit()

    # 文件
    elif os.path.isfile(s):
        if os.path.isfile(d):
            fcp(s, d, show_size_on=mshow)
        elif os.path.isdir(d):
            d = d + '/' + os.path.basename(s)
            fcp(s, d, show_size_on=mshow)    
        elif os.path.isdir(os.path.dirname(d)):
            fcp(s, d, show_size_on=mshow)    
        else:
            print 'Not found file:', d

    # 目录递归
    elif os.path.isdir(s) :
        if (os.path.isfile(d)):
            print 'cp :', '\'' + s + '\'', 'and', '\'' + d + '\'', ': are the same file'
            sys.exit()
        elif not os.access(s, os.R_OK):
            print d, ': Permission denied'
            sys.exit()
        elif s in d:
            print '\'' + s + '\'', 'to', '\'' + d + '\'', ": File error"
            sys.exit()
        # 确定目标文件夹根路径（只调用一次）
        elif (jc == 0):
            jc += 1
            if os.path.isdir(d):
                d = d + '/' + os.path.basename(s)

        if os.path.isdir(os.path.dirname(d)):
            if not os.path.isdir(d):
                os.mkdir(d)
        else:
            print  'Not found :', os.path.dirname(d)
            sys.exit()

        for x in os.listdir(s):
                dcp(s + '/' + x , d + '/' + x , jc , mshow=mshow)

    elif not os.path.exists(s):
        print s, ': No such file or directory'



def show_size(total_size , tail_size , filename , minute_size):
    filename = (filename) + ' ' * (50 - len(filename))

    # 百分比
    if (tail_size != total_size):
        rate = (float(tail_size) / float(total_size) * 100)
        rate_sum = '%d%s' % (rate, '%')
    else:
        rate_sum = str(100) + '%' 

    # 进度条
    jd_size = '*' * (int(float(tail_size) / float(total_size) * 50))
    jd_size = '[%s%s]' % (jd_size , (' ' * (50 - len(jd_size))))

    # 速度
    i = 0
    # minute_size = minute_size / 2
    while (minute_size >= 1024 and i <= 2):
        minute_size = float(minute_size) / float(1024)
        i = i + 1
    else:
        if i == 0:
            minute_size = str(round(minute_size, 1)) + 'k/s'
        elif i == 1:
            minute_size = str(round(minute_size, 1)) + 'kB/s'
        elif i == 2:
            minute_size = str(round(minute_size, 1)) + 'MB/s'
    minute_size = '%s%s' % (minute_size , (' ' * (10 - len(str(minute_size)))))

    # 已经复制大小
    i = 0
    while (tail_size >= 1024 and i < 2):
        tail_size = float(tail_size) / float(1024)
        i = i + 1
    else:
        if i == 0 :
            tail_size = str(round(tail_size)) + 'K'
        elif i == 1:
            tail_size = str(round(tail_size)) + 'KB'
        elif i == 2:
            tail_size = str(round(tail_size)) + 'M'

    print '\r', filename , rate_sum , jd_size , minute_size , '|' , tail_size, '   ',
    sys.stdout.flush()



if __name__ == '__main__':
    sys_type = platform.system()

    if (sys_type == 'Windows'):
        
        sfile = raw_input('source File:')
        dfile = raw_input('destination File:')

        try:
            dcp(sfile, dfile)
        except KeyboardInterrupt:
            sys.exit()
        os.system('pause')

    else:
        filelist = []
        for x in sys.argv[1:]:
            if not re.match('-(.*)$', x):
                filelist.append(x)
        if (len(filelist) == 2):

            try:
                dcp(filelist[0] , filelist[1] , mshow=1)
            except KeyboardInterrupt:
                sys.exit()
        else:
            print '[ERROR]'
            print '  example :[ cp sfile dfile ]'
    
